﻿using P2P.Client.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using P2P.Client.Buffer;

namespace P2P.Client
{
    public class ApiHandler
    {
        public static object Process(Socket s, IPEndPoint remoteEndPoint, string buffer)
        {
            ApiProtocol apiProtocol = new ApiProtocol(s, remoteEndPoint, buffer);

            if (string.IsNullOrEmpty(apiProtocol.ApiName))
            {
                return R<string>.Failed((int)StatusCode.API_NOT_FOUND);
            }

            return Invoke(apiProtocol.ApiName, apiProtocol);
        }

        public static object Invoke(string apiName, ApiProtocol apiProtocol)
        {
            Api api = ApiRoute.ApiMap[apiName];

            if (api == null)
            {
                return R<string>.Failed((int)StatusCode.API_NOT_FOUND);
            }

            if (!api.Version.Equals(apiProtocol.Version))
            {
                return R<string>.Failed((int)StatusCode.API_VERSION_NOT_MATCH);
            }

            if (api.Method != null && !api.Method.Contains(apiProtocol.Method))
            {
                return R<string>.Failed((int)StatusCode.REQUEST_MODE_ERROR);
            }

            try
            {
                Assembly assembly = Assembly.GetExecutingAssembly();

                Type type = assembly.GetType(api.Handler);

                object instance = Activator.CreateInstance(type, apiProtocol);

                MethodInfo method = type.GetMethod(apiProtocol.Method);

                return method.Invoke(instance, null);
            }
            catch (Exception e) { LogBuffer.Instance().Buffer.Enqueue(new Model.LogModel() { Log = e.Message, Time = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") }); }

            return null;
        }
    }
}
